<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script data-ezscrex='false' data-cfasync='false' data-pagespeed-no-defer>var __ez=__ez||{};__ez.stms=Date.now();__ez.evt={};__ez.script={};__ez.ck=__ez.ck||{};__ez.template={};__ez.template.isOrig=false;__ez.queue=function(){var e=0,i=0,t=[],n=!1,o=[],r=[],s=!0,a=function(e,i,n,o,r,s,a){var l=arguments.length>7&&void 0!==arguments[7]?arguments[7]:window,d=this;this.name=e,this.funcName=i,this.parameters=null===n?null:p(n)?n:[n],this.isBlock=o,this.blockedBy=r,this.deleteWhenComplete=s,this.isError=!1,this.isComplete=!1,this.isInitialized=!1,this.proceedIfError=a,this.fWindow=l,this.isTimeDelay=!1,this.process=function(){f("... func = "+e),d.isInitialized=!0,d.isComplete=!0,f("... func.apply: "+e);var i=d.funcName.split("."),n=null,o=this.fWindow||window;i.length>3||(n=3===i.length?o[i[0]][i[1]][i[2]]:2===i.length?o[i[0]][i[1]]:o[d.funcName]),null!=n&&n.apply(null,this.parameters),!0===d.deleteWhenComplete&&delete t[e],!0===d.isBlock&&(f("----- F'D: "+d.name),u())}},l=function(e,i,t,n,o,r,s){var a=arguments.length>7&&void 0!==arguments[7]?arguments[7]:window,l=this;this.name=e,this.path=i,this.async=o,this.defer=r,this.isBlock=t,this.blockedBy=n,this.isInitialized=!1,this.isError=!1,this.isComplete=!1,this.proceedIfError=s,this.fWindow=a,this.isTimeDelay=!1,this.isPath=function(e){return"/"===e[0]&&"/"!==e[1]},this.getSrc=function(e){return void 0!==window.__ezScriptHost&&this.isPath(e)&&"banger.js"!==this.name?window.__ezScriptHost+e:e},this.process=function(){l.isInitialized=!0,f("... file = "+e);var i=this.fWindow?this.fWindow.document:document,t=i.createElement("script");t.src=this.getSrc(this.path),!0===o?t.async=!0:!0===r&&(t.defer=!0),t.onerror=function(){var e={url:window.location.href,name:l.name,path:l.path,user_agent:window.navigator.userAgent};"undefined"!=typeof _ezaq&&(e.pageview_id=_ezaq.page_view_id);var i=encodeURIComponent(JSON.stringify(e)),t=new XMLHttpRequest;t.open("GET","//g.ezoic.net/ezqlog?d="+i,!0),t.send(),f("----- ERR'D: "+l.name),l.isError=!0,!0===l.isBlock&&u()},t.onreadystatechange=t.onload=function(){var e=t.readyState;f("----- F'D: "+l.name),e&&!/loaded|complete/.test(e)||(l.isComplete=!0,!0===l.isBlock&&u())},i.getElementsByTagName("head")[0].appendChild(t)}},d=function(e,i){this.name=e,this.path="",this.async=!1,this.defer=!1,this.isBlock=!1,this.blockedBy=[],this.isInitialized=!0,this.isError=!1,this.isComplete=i,this.proceedIfError=!1,this.isTimeDelay=!1,this.process=function(){}};function c(e){!0!==h(e)&&0!=s&&e.process()}function h(e){if(!0===e.isTimeDelay&&!1===n)return f(e.name+" blocked = TIME DELAY!"),!0;if(p(e.blockedBy))for(var i=0;i<e.blockedBy.length;i++){var o=e.blockedBy[i];if(!1===t.hasOwnProperty(o))return f(e.name+" blocked = "+o),!0;if(!0===e.proceedIfError&&!0===t[o].isError)return!1;if(!1===t[o].isComplete)return f(e.name+" blocked = "+o),!0}return!1}function f(e){var i=window.location.href,t=new RegExp("[?&]ezq=([^&#]*)","i").exec(i);"1"===(t?t[1]:null)&&console.debug(e)}function u(){++e>200||(f("let's go"),m(o),m(r))}function m(e){for(var i in e)if(!1!==e.hasOwnProperty(i)){var t=e[i];!0===t.isComplete||h(t)||!0===t.isInitialized||!0===t.isError?!0===t.isError?f(t.name+": error"):!0===t.isComplete?f(t.name+": complete already"):!0===t.isInitialized&&f(t.name+": initialized already"):t.process()}}function p(e){return"[object Array]"==Object.prototype.toString.call(e)}return window.addEventListener("load",(function(){setTimeout((function(){n=!0,f("TDELAY -----"),u()}),5e3)}),!1),{addFile:function(e,i,n,s,a,d,h,f,u){var m=new l(e,i,n,s,a,d,h,u);!0===f?o[e]=m:r[e]=m,t[e]=m,c(m)},addDelayFile:function(e,i){var n=new l(e,i,!1,[],!1,!1,!0);n.isTimeDelay=!0,f(e+" ...  FILE! TDELAY"),r[e]=n,t[e]=n,c(n)},addFunc:function(e,n,s,l,d,h,f,u,m,p){!0===h&&(e=e+"_"+i++);var w=new a(e,n,s,l,d,f,u,p);!0===m?o[e]=w:r[e]=w,t[e]=w,c(w)},addDelayFunc:function(e,i,n){var o=new a(e,i,n,!1,[],!0,!0);o.isTimeDelay=!0,f(e+" ...  FUNCTION! TDELAY"),r[e]=o,t[e]=o,c(o)},items:t,processAll:u,setallowLoad:function(e){s=e},markLoaded:function(e){if(e&&0!==e.length){if(e in t){var i=t[e];!0===i.isComplete?f(i.name+" "+e+": error loaded duplicate"):(i.isComplete=!0,i.isInitialized=!0)}else t[e]=new d(e,!0);f("markLoaded dummyfile: "+t[e].name)}},logWhatsBlocked:function(){for(var e in t)!1!==t.hasOwnProperty(e)&&h(t[e])}}}();__ez.evt.add=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent?e.attachEvent("on"+t,n):e["on"+t]=n()},__ez.evt.remove=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent?e.detachEvent("on"+t,n):delete e["on"+t]};__ez.script.add=function(e){var t=document.createElement("script");t.src=e,t.async=!0,t.type="text/javascript",document.getElementsByTagName("head")[0].appendChild(t)};__ez.dot={};__ez.queue.addFile('/detroitchicago/boise.js', '/detroitchicago/boise.js?gcb=195-2&cb=2', true, [], true, false, true, false);__ez.queue.addFile('/parsonsmaize/abilene.js', '/parsonsmaize/abilene.js?gcb=195-2&cb=28', true, [], true, false, true, false);</script>
<script data-ezscrex="false" type="text/javascript" data-cfasync="false">window._ezaq = Object.assign({}, typeof window._ezaq !== "undefined" ? window._ezaq : {}, {"ad_cache_level":1,"domain_id":173770,"ezcache_level":1,"ezcache_skip_code":0,"has_bad_image":0,"has_bad_words":0,"is_sitespeed":0,"lt_cache_level":0,"page_view_id":"6b5ecb9b-8268-4ac3-5ce1-ce207e533b6d","response_size_orig":38532,"response_time_orig":591,"template_id":134,"url":"https://plantuml.com/smetana01","word_count":1374,"worst_bad_word_level":0});__ez.queue.markLoaded('ezaqBaseReady');</script>
<script type="text/javascript">(function(){function storageAvailable(type){var storage;try{storage=window[type];var x='__storage_test__';storage.setItem(x,x);storage.removeItem(x);return true;}
catch(e){return e instanceof DOMException&&(e.code===22||e.code===1014||e.name==='QuotaExceededError'||e.name==='NS_ERROR_DOM_QUOTA_REACHED')&&(storage&&storage.length!==0);}}
function remove_ama_config(){if(storageAvailable('localStorage')){localStorage.removeItem("google_ama_config");}}
remove_ama_config()})()</script>
<script type="text/javascript">var ezoicTestActive = true</script>
<script data-ezscrex="false" type="text/javascript" data-cfasync="false">window._ezaq = Object.assign({}, typeof window._ezaq !== "undefined" ? window._ezaq : {}, {"ab_test_id":"mod174-c","ad_cache_level":1,"ad_count_adjustment":0,"ad_lazyload_version":0,"ad_load_version":1,"ad_location_ids":"","adx_ad_count":0,"ai_placeholder_cache_level":1,"ai_placeholder_placement_cnt":-1,"bidder_method":1,"bidder_version":3,"city":"Krasnoyarsk","country":"RU","days_since_last_visit":-1,"display_ad_count":0,"domain_id":173770,"domain_test_group":20230802,"ds_adsize_opt_id":-1,"engaged_time_visit":0,"ezcache_level":1,"ezcache_skip_code":0,"form_factor_id":1,"framework_id":1,"has_bad_image":0,"has_bad_words":0,"iab_category":"","iab_category_0":"596","is_embed":false,"is_from_recommended_pages":false,"is_return_visitor":false,"is_sitespeed":0,"last_page_load":"","last_pageview_id":"","lt_cache_level":0,"max_ads":0,"metro_code":0,"optimization_version":1,"page_ad_positions":"","page_view_count":1204,"page_view_id":"6b5ecb9b-8268-4ac3-5ce1-ce207e533b6d","position_selection_id":0,"postal_code":"660000","pv_event_count":0,"response_size_orig":38532,"response_time_orig":591,"serverid":"i-0e83ca0e340538c83","state":"KYA","sub_page_ad_positions":"","t_epoch":1697691244,"template_id":134,"time_on_site_visit":0,"url":"https://plantuml.com/smetana01","word_count":1374,"worst_bad_word_level":0});__ez.queue.markLoaded('ezaqReady');</script>
<script data-ezscrex='false' data-cfasync='false' data-pagespeed-no-defer>__ez.queue.addFile('/parsonsmaize/mulvane.js', '/parsonsmaize/mulvane.js?gcb=195-2&cb=5', true, ['/parsonsmaize/abilene.js'], true, false, true, false);__ez.queue.addFile('/parsonsmaize/olathe.js', '/parsonsmaize/olathe.js?gcb=195-2&cb=20', false, ['/parsonsmaize/abilene.js','/parsonsmaize/mulvane.js'], true, false, true, false);__ez.queue.addFile('/porpoiseant/et.js', '/porpoiseant/et.js?gcb=195-2&cb=2', false, [], true, false, true, false);!function(){var e;__ez.vep=(e=[],{Add:function(i,t){__ez.dot.isDefined(i)&&__ez.dot.isValid(t)&&e.push({type:"video",video_impression_id:i,domain_id:__ez.dot.getDID(),t_epoch:__ez.dot.getEpoch(0),data:__ez.dot.dataToStr(t)})},Fire:function(){if(void 0===document.visibilityState||"prerender"!==document.visibilityState){if(__ez.dot.isDefined(e)&&e.length>0)for(;e.length>0;){var i=5;i>e.length&&(i=e.length);var t=e.splice(0,i),o=__ez.dot.getURL("/detroitchicago/grapefruit.gif")+"?orig="+(!0===__ez.template.isOrig?1:0)+"&v="+btoa(JSON.stringify(t));__ez.dot.Fire(o)}e=[]}}})}();</script><script data-ezscrex='false' data-cfasync='false' data-pagespeed-no-defer>!function(){function e(i){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(i)}__ez.pel=function(){var i=[];function t(t,o,d,_,n,r,a,s){if(__ez.dot.isDefined(t)&&0!=__ez.dot.isAnyDefined(t.getSlotElementId,t.ElementId)){void 0===s&&(s=!1);var p=parseInt(__ez.dot.getTargeting(t,"ap")),f=__ez.dot.getSlotIID(t),u=__ez.dot.getAdUnit(t,s),z=parseInt(__ez.dot.getTargeting(t,"compid")),g=0,c=0,l=function(i){if("undefined"==typeof _ezim_d)return!1;var t=__ez.dot.getAdUnitPath(i).split("/").pop();if("object"===("undefined"==typeof _ezim_d?"undefined":e(_ezim_d))&&_ezim_d.hasOwnProperty(t))return _ezim_d[t];for(var o in _ezim_d)if(o.split("/").pop()===t)return _ezim_d[o];return!1}(t);"object"==e(l)&&(void 0!==l.creative_id&&(c=l.creative_id),void 0!==l.line_item_id&&(g=l.line_item_id)),__ez.dot.isDefined(f,u)&&__ez.dot.isValid(o)&&("0"===f&&!0!==s||""===u||i.push({type:"impression",impression_id:f,domain_id:__ez.dot.getDID(),unit:u,t_epoch:__ez.dot.getEpoch(0),revenue:d,est_revenue:_,ad_position:p,ad_size:"",bid_floor_filled:n,bid_floor_prev:r,stat_source_id:a,country_code:__ez.dot.getCC(),pageview_id:__ez.dot.getPageviewId(),comp_id:z,line_item_id:g,creative_id:c,data:__ez.dot.dataToStr(o),is_orig:s||__ez.template.isOrig}))}}function o(){void 0!==document.visibilityState&&"prerender"===document.visibilityState||(__ez.dot.isDefined(i)&&i.length>0&&[i.filter((function(e){return e.is_orig})),i.filter((function(e){return!e.is_orig}))].forEach((function(e){for(;e.length>0;){var i=e[0].is_orig||!1,t=5;t>e.length&&(t=e.length);var o=e.splice(0,t),d=__ez.dot.getURL("/porpoiseant/army.gif")+"?orig="+(!0===i?1:0)+"&sts="+btoa(JSON.stringify(o));(void 0!==window.isAmp&&isAmp||void 0!==window.ezWp&&ezWp)&&void 0!==window._ezaq&&_ezaq.hasOwnProperty("domain_id")&&(d+="&visit_uuid="+_ezaq.visit_uuid),__ez.dot.Fire(d)}})),i=[])}return{Add:t,AddAndFire:function(e,i){t(e,i,0,0,0,0,0),o()},AddAndFireOrig:function(e,i){t(e,i,0,0,0,0,0,!0),o()},AddById:function(e,t,o,d){var _=e.split("/");if(__ez.dot.isDefined(e)&&3===_.length&&__ez.dot.isValid(t)){var n=_[0],r={type:"impression",impression_id:_[2],domain_id:__ez.dot.getDID(),unit:n,t_epoch:__ez.dot.getEpoch(0),pageview_id:__ez.dot.getPageviewId(),data:__ez.dot.dataToStr(t),is_orig:o||__ez.template.isOrig};void 0!==d&&(r.revenue=d),i.push(r)}},Fire:o,GetPixels:function(){return i}}}()}();__ez.queue.addFile('/detroitchicago/raleigh.js', '/detroitchicago/raleigh.js?gcb=195-2&cb=6', false, ['/parsonsmaize/abilene.js'], true, false, true, false);__ez.queue.addFile('/detroitchicago/vista.js', '/detroitchicago/vista.js?gcb=195-2&cb=5', false, ['/parsonsmaize/abilene.js'], true, false, true, false);__ez.queue.addFile('/detroitchicago/tampa.js', '/detroitchicago/tampa.js?gcb=195-2&cb=5', false, ['/parsonsmaize/abilene.js'], true, false, true, false);</script><base href=""/><meta name="flattr:id" content="1ew3x0"/><script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Organization",
  "url": "https://plantuml.com",
  "name": "PlantUML",
  "sameAs" : ["https://twitter.com/plantuml","https://en.wikipedia.org/wiki/PlantUML","https://www.wikidata.org/wiki/Q18346546"],
  "logo": "https://cdn-0.plantuml.com/logo3.png",
  "contactPoint": [{
    "@type": "ContactPoint",
    "email": "plantuml@gmail.com",
    "url": "https://plantuml.com",
    "contactType": "customer service"
  }]
}
</script><link rel="canonical" href="smetana01.html"/><link rel="alternate" hreflang="x-default" href="smetana01.html"/><link rel="alternate" hreflang="de" href="https://plantuml.com/de/smetana01"/><link rel="alternate" hreflang="en" href="smetana01.html"/><link rel="alternate" hreflang="es" href="https://plantuml.com/es/smetana01"/><link rel="alternate" hreflang="fr" href="https://plantuml.com/fr/smetana01"/><link rel="alternate" hreflang="ja" href="https://plantuml.com/ja/smetana01"/><link rel="alternate" hreflang="ru" href="https://plantuml.com/ru/smetana01"/><link rel="alternate" hreflang="ko" href="https://plantuml.com/ko/smetana01"/><link rel="alternate" hreflang="zh" href="https://plantuml.com/zh/smetana01"/><link rel="shortcut icon" href="favicon.ico"/><link rel="preload" as="image" href="svgrepo-house.svg"/><link rel="preload" as="image" href="svgrepo-text-news.svg"/><link rel="preload" as="image" href="svgrepo-rocket-3-start.svg"/><link rel="preload" as="image" href="svgrepo-server.svg"/><link rel="preload" as="image" href="svgrepo-play.svg"/><link rel="preload" as="image" href="svgrepo-forum.svg"/><link rel="preload" as="image" href="svgrepo-add-to-online-cart.svg"/><link rel="preload" as="image" href="svgrepo-forum-message.svg"/><link rel="preload" as="image" href="svgrepo-palette-fill.svg"/><link rel="preload" as="image" href="svgrepo-cpu.svg"/><link rel="preload" as="image" href="svgrepo-books-library.svg"/><link rel="preload" as="image" href="svgrepo-signpost-fill.svg"/><link rel="preload" as="image" href="svgrepo-library.svg"/><link rel="preload" as="image" href="flags21.png"/><link rel="preload" as="image" href="svgrepo-uxwing-light-mode-toggle.svg"/><meta property="og:type" content="article"/><meta property="og:url" content="https://plantuml.com/smetana01"/><meta property="og:site_name" content="PlantUML.com"/><meta name="twitter:image" content="https://plantuml.com/og-smetana01"/><meta property="og:locale" content="en"/><meta name="twitter:card" content="summary"/><meta name="twitter:site" content="@PlantUML"/><meta name="twitter:creator" content="@PlantUML"/><script>if(window.location.href.indexOf("/en/")==-1){var lg=navigator.language.substring(0,2);if(lg=="de"){window.location.href="/de/smetana01"}if(lg=="es"){window.location.href="/es/smetana01"}if(lg=="fr"){window.location.href="/fr/smetana01"}if(lg=="ja"){window.location.href="/ja/smetana01"}if(lg=="ko"){window.location.href="/ko/smetana01"}if(lg=="ru"){window.location.href="/ru/smetana01"}if(lg=="zh"){window.location.href="/zh/smetana01"}};</script><style>li{margin:2px}#external li{margin:13px}.pezoic{max-width:970px}@media screen and (max-width:1600px){.pezoic{max-width:768px}}.coptable{max-width:90%}.mytab{display:inline-block;border-radius:3px;border:1px solid #e1e4e8}.mytab:hover{border:1px dashed #0366d6;cursor:pointer;color:#0366d6;background:#f6f8fa}.cop{margin:25px 10px 0 10px}.cop:hover{cursor:pointer;filter:invert(30%) sepia(75%) saturate(4001%) hue-rotate(201deg) brightness(88%) contrast(98%)}.cop2{margin:25px 10px 0 10px}.cop2:hover{cursor:pointer}.msg{position:absolute;color:#396;background-color:#FFF;margin-top:55px;display:none;border-radius:3px;border:1px solid #4dff00}.mycell0{float:left;vertical-align:top;padding:10px}.mycell0 code:hover{cursor:default;color:#000}.mycell{float:right;vertical-align:top;padding:10px;max-width:55vw;overflow-x:auto}.mycell0 pre{max-width:55vw;overflow-x:auto}.cod{background:#edeff3;padding:2px 5px;border-radius:3px}.colo{display:inline-block;background:#edeff3;padding:7px 12px;border-radius:3px}.tag,.tagg,.tago,.tagr{text-rendering:optimizeLegibility;display:inline-block;padding:3px 5px 2px 4px;text-decoration:none;white-space:nowrap;border:1px solid #999;text-transform:uppercase;text-align:center;border-radius:3px;font-size:11px;font-weight:bold;line-height:90%}.tag{background-color:#eee}.tagg{background-color:#98fb98}.tago{background-color:#fafa00}.tagr{background-color:#ff4500}a{text-decoration:none;color:#0366d6}a:hover{text-decoration:underline}.menu1{border:0;font-family:Helvetica,sans-serif;font-size:14px;padding:0;margin:0;white-space:nowrap;overflow:hidden;vertical-align:middle;line-height:30px}.menu1 a{text-align:center;padding:10px 7px 10px 7px;text-decoration:none;color:#637282}.menu1 a:hover{color:#0366d6}#menu0{top:0;z-index:4;margin:0 0 0 10px;padding:0}@media screen and (max-width:1200px){#menu0{visibility:hidden}}.mhov img{margin:0 5px 0 0;padding:0}.mhov:hover{filter:invert(25%) sepia(97%) saturate(2026%) hue-rotate(201deg) brightness(91%) contrast(98%)}#menuside2{border:0;font-family:Helvetica,sans-serif;font-size:14px;padding:20px 0 4px 0;margin:0}#menuside2 span{vertical-align:top}#menuside2 li{list-style:none;position:relative;padding:0;margin:10px 20px 10px 10px;border:0}#menuside2 li a{display:inline-block;text-decoration:none;color:#637282;width:100%}#BC{z-index:0;padding-top:5px;top:35px}.breadcrumb{z-index:1;font-family:Helvetica,sans-serif;font-size:14px;text-align:center;display:inline-block;overflow:hidden;border-radius:5px}.breadcrumb a{text-decoration:none;outline:0;display:block;float:left;font-size:12px;line-height:24px;color:#373f49;padding:0 10px 0 35px;background:#f0f1f1;background:linear-gradient(#f0f1f1,#c6d2d2);position:relative}.breadcrumb a:first-child{padding-left:21px;border-radius:5px 0 0 5px}.breadcrumb a:first-child:before{left:14px}.breadcrumb a:last-child{visibility:hidden}.breadcrumb a.active,.breadcrumb a:hover{color:#0366d6;background:#c6d2d2;background:linear-gradient(#e3e4e4,#b8c7c7)}.breadcrumb a.active:after,.breadcrumb a:hover:after{background:#c6d2d2;background:linear-gradient(135deg,#e3e4e4,#b8c7c7)}.breadcrumb a:after{content:'';position:absolute;top:0;right:-12px;width:24px;height:24px;transform:scale(0.707) rotate(45deg);z-index:1;background:#f0f1f1;background:linear-gradient(135deg,#f0f1f1,#c6d2d2);box-shadow:2px -2px 0 2px rgba(0,0,0,0.1),3px -3px 0 2px rgba(255,255,255,0.1);border-radius:0 5px 0 50px}.breadcrumb a:last-child:after{content:none;visibility:hidden}.lga,.lga a,.lgi,.lgi a{font-family:Helvetica,sans-serif;font-size:13px;text-align:center;color:#fff;padding:0 5px;margin:0}.lga,.lga a{background-color:#008}.lgi,.lgi a{background-color:#888}.lga:hover,.lga:hover a{text-decoration:none;color:#BBB}.lgi:hover,.lgi:hover a{text-decoration:none;color:#CCC}</style><style>.backtop{margin:0 10px}.backtop:hover{cursor:pointer;filter:invert(30%) sepia(75%) saturate(4001%) hue-rotate(201deg) brightness(88%) contrast(98%)}</style><style>.dropbtn{padding:0;border:0;background:0}.dropdown{position:relative;display:inline-block;margin:0 10px}.dropdown-content{display:none;position:absolute;background-color:#f1f1f1;min-width:160px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.dropdown-content img{vertical-align:middle;margin:0 8px 0 1px}.dropdown-content a{font-size:small;font-weight:normal;color:black;padding:5px 10px;text-decoration:none;display:block}.dropdown-content a:hover{background-color:#ddd;color:#0366d6}.dropdown:hover .dropdown-content{display:block}.dropdown:hover .dropbtn{background-color:#3e8e41}</style><style>#flex1{margin:0;padding:0;display:flex;flex-direction:row;width:378px;height:100%}#lll{flex-grow:1;flex-shrink:1;max-width:162px;overflow:hidden}#mmm{flex-grow:0;flex-shrink:0;background:#edeff3;width:210px;min-width:210px;max-width:210px;flex-grow:0;flex-shrink:0;border-left:1px solid #d4d8de}#qqq{flex-grow:0;flex-shrink:0;width:4px;min-width:4px;max-width:4px;flex-grow:0;flex-shrink:0}#rrr{flex-grow:1;flex-shrink:1;max-width:162px;overflow:hidden}.cde{display:flex;flex-direction:column;justify-content:space-between;height:100%}.cd{display:flex;flex-direction:column;justify-content:space-start;height:100%}.aaa{height:30px;min-height:30px;max-height:30px;flex-grow:0;flex-shrink:0;background:#edeff3;border-bottom:1px solid #d4d8de}.bbb,.bbborder{flex-grow:1;flex-shrink:0}.bbborder{border-left:1px solid #d4d8de}#header{z-index:10;position:fixed;left:378px;right:0;height:30px;top:0;background:#edeff3;border-bottom:1px solid #d4d8de}#header2{z-index:7;position:fixed;left:378px;right:0;height:10px;top:30px;background:#fefefe}#left0{top:0;position:fixed;left:0;margin:0;bottom:0;width:378px;padding:0;z-index:2}#root{padding:0;margin:40px 0 0 388px;background:#fefefe}body{margin:auto;overflow-x:hidden;background:#fefefe}@media screen and (max-width:1190px){#flex1,#left0{width:215px}#root{margin:40px 0 0 224px}#header,#header2{left:215px}#left0{left:0}#lll,#rrr{width:0;visibility:hidden;flex-grow:0;flex-shrink:0}}@media screen and (max-width:1010px){#root{margin:0 0 0 216px}#header,#header2{display:none}#lll,#qqq{width:0;visibility:hidden;flex-grow:0;flex-shrink:0}#mmm{border-right:1px solid #d4d8de}}@media screen and (min-width:1700px){#header,#header2{left:518px}#left0,#flex1{width:518px}#root{margin-left:528px}#lll,#rrr{max-width:302px}}</style><script>window.pushMST_config={vapidPK:"BBodn2vLFoDO5AdCfmOOzNmcUsn52kTA6JNZNYVFymzEdWHonz_bkUcsaTkPXHvNGRkRUSAxMbup-H0l2sb1h_Q",enableOverlay:true,swPath:"/sw.js",i18n:{}};var pushmasterTag=document.createElement("script");pushmasterTag.src="https://cdn.pushmaster-cdn.xyz/scripts/publishers/629f5e297baecc00098a271b/SDK.js";pushmasterTag.setAttribute("defer","");var firstScriptTag=document.getElementsByTagName("script")[0];firstScriptTag.parentNode.insertBefore(pushmasterTag,firstScriptTag);</script><script async="" src="https://www.googletagmanager.com/gtag/js?id=G-TKZNNQT9CZ"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date());gtag("config","G-TKZNNQT9CZ");</script><script>var llg="en";var az=0;var amdark=0;function ljs(b){if(az){return false}var a=document.createElement("script");a.type="text/javascript";a.src="/btn-"+b+".js";document.body.innerHTML="<i style='position:absolute;top:30%;width:100%;'><center>Loading in progress...";document.body.appendChild(a)}function ctc(c){document.getElementById("img"+c).classList.remove("cop");document.getElementById("img"+c).classList.add("cop2");document.getElementById("pre"+c).style.backgroundColor="#4dff00";document.getElementById("msg"+c).style.display="inline";setTimeout(function(){document.getElementById("img"+c).classList.remove("cop2");document.getElementById("img"+c).classList.add("cop");document.getElementById("pre"+c).style.backgroundColor="";document.getElementById("msg"+c).style.display="none"},800);text=document.getElementById("pre"+c).innerText;if(window.clipboardData&&window.clipboardData.setData){return window.clipboardData.setData("Text",text)}else{if(document.queryCommandSupported&&document.queryCommandSupported("copy")){var a=document.createElement("textarea");a.textContent=text;a.style.position="fixed";document.body.appendChild(a);a.select();try{return document.execCommand("copy")}catch(b){return false}finally{document.body.removeChild(a)}}}};</script><script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><script type='text/javascript'>
var ezoTemplate = 'pub_site';
var ezouid = '1';
var ezoFormfactor = '1';
</script><script data-ezscrex="false" type='text/javascript'>
var soc_app_id = '0';
var did = 173770;
var ezdomain = 'plantuml.com';
var ezoicSearchable = 1;
</script>
<script data-ezscrex='false' data-pagespeed-no-defer data-cfasync='false'>
function create_ezolpl() {
	var d = new Date();
	d.setTime(d.getTime() + (365*24*60*60*1000));
	var expires = "expires="+d.toUTCString();
	__ez.ck.setByCat("ezux_lpl_173770=" + new Date().getTime() + "|" + _ezaq.page_view_id + "|" + _ezaq.is_return_visitor + "; " + expires, 3);
}
function attach_ezolpl() {
	if (document.readyState === "complete") {
		create_ezolpl();
		return;
	}
	window.addEventListener("load", create_ezolpl);
}

__ez.queue.addFunc("attach_ezolpl", "attach_ezolpl", null, false, ['/detroitchicago/boise.js'], true, false, false, false);
</script></head><body><div id="left0"><div id="flex1"><div id="lll"><div class="cde"><div></div><div><span id="ezoic-pub-ad-placeholder-131"></span><!-- ezoic_pub_ad_placeholder-131-sidebar-120x600-131-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-131-sidebar-160x600-131-nonexxxnonexxxxxxezmaxscaleval100 --></div><div></div></div></div><div id="mmm"><div class="cde"><div><div><span id="ezoic-pub-ad-placeholder-105"></span><!-- ezoic_pub_ad_placeholder-105-sidebar_middle-120x240-105-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-105-sidebar_middle-125x125-105-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-105-sidebar_middle-180x150-105-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-105-sidebar_middle-200x200-105-nonexxxnonexxxxxxezmaxscaleval100 --></div><ul id="menuside2"><li><a href="index.html" class="mhov"><img src="svgrepo-house.svg" width="16" height="16"/><span>Home</span></a></li><li><a href="news.html" class="mhov"><img src="svgrepo-text-news.svg" width="16" height="16"/><span>What&#39;s New ?</span></a></li><li><a href="starting.html" class="mhov"><img src="svgrepo-rocket-3-start.svg" width="16" height="16"/><span>Getting Started</span></a></li><li><a href="https://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000" class="mhov"><img src="svgrepo-server.svg" width="16" height="16"/><span>Online Server</span></a></li><li><a href="running.html" class="mhov"><img src="svgrepo-play.svg" width="16" height="16"/><span>Running</span></a></li><li><a href="faq.html" class="mhov"><img src="svgrepo-forum.svg" width="16" height="16"/><span>F.A.Q.</span></a></li><li><a href="download.html" class="mhov"><img src="svgrepo-add-to-online-cart.svg" width="16" height="16"/><span>Download</span></a></li><li><a href="qa.html" class="mhov"><img src="svgrepo-forum-message.svg" width="16" height="16"/><span>Forum</span></a></li><li><a href="theme.html" class="mhov"><img src="svgrepo-palette-fill.svg" width="16" height="16"/><span>Theme</span></a></li><li><a href="preprocessing.html" class="mhov"><img src="svgrepo-cpu.svg" width="16" height="16"/><span>Preprocessing</span></a></li><li><a href="stdlib.html" class="mhov"><img src="svgrepo-books-library.svg" width="16" height="16"/><span>Standard Library</span></a></li><li><a href="https://crashedmind.github.io/PlantUMLHitchhikersGuide" class="mhov"><img src="svgrepo-signpost-fill.svg" width="16" height="16"/><span>Hitchhiker&#39;s Guide</span></a></li><li><a href="guide.html" class="mhov"><img src="svgrepo-library.svg" width="16" height="16"/><span>PDF Guide</span></a></li></ul><div><span id="ezoic-pub-ad-placeholder-108"></span><!-- ezoic_pub_ad_placeholder-108-sidebar_middle-120x240-108-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-108-sidebar_middle-125x125-108-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-108-sidebar_middle-180x150-108-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-108-sidebar_middle-200x200-108-nonexxxnonexxxxxxezmaxscaleval100 --></div></div><div></div><div style="margin-bottom:35px;"><span id="ezoic-pub-ad-placeholder-186"></span><!-- ezoic_pub_ad_placeholder-186-sidebar_middle-120x240-186-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-186-sidebar_middle-125x125-186-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-186-sidebar_middle-180x150-186-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-186-sidebar_middle-200x200-186-nonexxxnonexxxxxxezmaxscaleval100 --></div></div></div><div id="qqq"><div class="cd"><div class="aaa"></div><div class="bbborder"></div></div></div><div id="rrr"><div class="cd"><div class="aaa"></div><div style="height:5px;"></div><div class="bbb"><div class="cde"><div></div><div><span id="ezoic-pub-ad-placeholder-175"></span><!-- ezoic_pub_ad_placeholder-175-sidebar-120x600-175-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-175-sidebar-160x600-175-nonexxxnonexxxxxxezmaxscaleval100 --></div><div></div></div></div></div></div></div></div><style>#contmenu{display:flex;height:30px;width:100%;margin:0;padding:0}#contmenua{height:30px;padding-right:25px}#contmenub{z-index:15;display:inline-block;flex-grow:1;flex-shrink:1;height:30px;background-color:#edeff3}#magic{white-space:nowrap;overflow:hidden;z-index:14;position:fixed;top:0;right:50px;height:30px;width:30px}#magic2{white-space:nowrap;overflow:hidden;z-index:16;position:fixed;top:0;right:0;height:30px;width:50px;background-color:#edeff3}#magic2 img{margin:5px 0 0 5px;filter:invert(44%) sepia(27%) saturate(310%) hue-rotate(170deg) brightness(92%) contrast(83%)}#magic2:hover img{filter:invert(25%) sepia(97%) saturate(2026%) hue-rotate(201deg) brightness(91%) contrast(98%)}#magic:hover #svgrepoleft{filter:invert(22%) sepia(53%) saturate(4563%) hue-rotate(202deg) brightness(95%) contrast(98%)}#magic:hover{width:100%;height:31px}#aze{height:30px;display:flex;flex-direction:row-reverse}#aze1{height:30px;background-color:#edeff3}#aze2{height:30px;background-color:#edeff3;padding-left:10px;border-left:1px solid #d4d8de;border-bottom:1px solid #d4d8de}#aze1 img{filter:invert(46%) sepia(6%) saturate(1254%) hue-rotate(171deg) brightness(94%) contrast(92%)}#aze3{width:3px;height:30px;background-color:#edeff3}</style><div id="header"><div id="contmenu"><div id="contmenua"><div class="menu1"><a href="sequence-diagram.html">Sequence</a><a href="use-case-diagram.html">Use Case</a><a href="class-diagram.html">Class</a><a href="activity-diagram-beta.html">Activity</a><a href="component-diagram.html">Component</a><a href="state-diagram.html">State</a><a href="object-diagram.html">Object</a><a href="deployment-diagram.html">Deployment</a><a href="timing-diagram.html">Timing</a><a href="nwdiag.html">Network</a><a href="salt.html">Wireframe</a><a href="archimate.html">Archimate</a><a href="gantt-diagram.html">Gantt</a><a href="mindmap-diagram.html">MindMap</a><a href="wbs-diagram.html">WBS</a><a href="json.html">JSON</a><a href="yaml.html">YAML</a></div></div><div id="contmenub"></div></div><div id="magic"><div id="aze"><div id="aze1"><img id="svgrepoleft" width="30" height="30" src="svgrepo-left.svg"/></div><div id="aze2"><div class="menu1"><a href="sequence-diagram.html">Sequence</a><a href="use-case-diagram.html">Use Case</a><a href="class-diagram.html">Class</a><a href="activity-diagram-beta.html">Activity</a><a href="component-diagram.html">Component</a><a href="state-diagram.html">State</a><a href="object-diagram.html">Object</a><a href="deployment-diagram.html">Deployment</a><a href="timing-diagram.html">Timing</a><a href="nwdiag.html">Network</a><a href="salt.html">Wireframe</a><a href="archimate.html">Archimate</a><a href="gantt-diagram.html">Gantt</a><a href="mindmap-diagram.html">MindMap</a><a href="wbs-diagram.html">WBS</a><a href="json.html">JSON</a><a href="yaml.html">YAML</a></div></div><div id="aze3"></div></div></div><div id="magic2"><a href="https://plantuml.com/en-dark/smetana01"><img src="svgrepo-uxwing-light-mode-toggle.svg" height="20"/></a></div></div><div id="header2"></div><div id="root"><style>#haut1{margin:50px 0 20px;padding:0;min-height:80px}#donate{padding-top:5px;min-height:30px}</style><div id="haut1"><div style="float:left;"><div class="breadcrumb"><a href="sitemap.html">PlantUML</a><a href="smetana01.html#"></a></div><div id="donate">   <a href="https://discord.gg/sXhzexAQGh" style="text-decoration: none;"><img src="https://img.shields.io/discord/1083727021328306236?color=5865F2&amp;logo=discord&amp;logoColor=white" alt="Discord server"/></a>   <a href="https://github.com/sponsors/plantuml/" style="text-decoration: none;"><img src="https://img.shields.io/github/sponsors/plantuml?logo=github"/></a>   <a href="https://www.patreon.com/bePatron?patAmt=1&amp;u=527450&amp;rid=152970" style="text-decoration: none;"><img src="https://img.shields.io/badge/patreon-122-chocolate?logo=patreon"/></a>   <a href="lp.html" style="text-decoration: none;"><img src="https://img.shields.io/liberapay/patrons/plantuml?color=gold&amp;logo=liberapay&amp;label=liberapay"/></a>   <a href="en/paypal.html" style="text-decoration: none;"><img src="https://img.shields.io/badge/paypal-296-skyblue?logo=paypal&amp;logoColor=red"/></a></div></div><div style="float:right; margin:3px 0;"><style>#langlist{display:flex;justify-content:space-between;width:317px;height:16px;margin:3px 10px 3px 0}.sel2{border:2px solid #fefefe}.nosel2{border:2px solid #fefefe;filter:grayscale(100%) opacity(75%)}.sel2:hover,.nosel2:hover{cursor:pointer;border:2px solid #0366d6;border-spacing:0;filter:grayscale(0);filter:contrast(200%);filter:brightness(150%)}#flag1,#flag2,#flag3,#flag4,#flag5,#flag6,#flag7,#flag8{background:url(flags21.png);background-repeat:no-repeat;background-clip:content-box;width:22px;height:16px}#flag2{background-position:-22px 0}#flag3{background-position:-44px 0}#flag4{background-position:-66px 0}#flag5{background-position:-88px 0}#flag6{background-position:-110px 0}#flag7{background-position:-132px 0}#flag8{background-position:-154px 0}</style><div id="langlist"><div id="flag1" onclick="location.href=&#39;/en/smetana01&#39;" class="sel2"></div><div id="flag2" onclick="location.href=&#39;/de/smetana01&#39;" class="nosel2"></div><div id="flag3" onclick="location.href=&#39;/es/smetana01&#39;" class="nosel2"></div><div id="flag4" onclick="location.href=&#39;/fr/smetana01&#39;" class="nosel2"></div><div id="flag5" onclick="location.href=&#39;/ja/smetana01&#39;" class="nosel2"></div><div id="flag6" onclick="location.href=&#39;/ko/smetana01&#39;" class="nosel2"></div><div id="flag7" onclick="location.href=&#39;/ru/smetana01&#39;" class="nosel2"></div><div id="flag8" onclick="location.href=&#39;/zh/smetana01&#39;" class="nosel2"></div></div></div></div><p><style>#topsticky{z-index:2;margin:0 240px 0 0}@media screen and (min-height:800px){#topsticky{position:sticky;top:40px}}@media screen and (max-width:1500px){#topsticky{margin:0}}</style></p><div id="topsticky"><span id="ezoic-pub-ad-placeholder-647"></span><!-- ezoic_pub_ad_placeholder-647-under_page_title-320x100-647-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-647-under_page_title-300x50v2-647-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-647-under_page_title-320x50-647-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-647-under_page_title-468x60-647-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-647-under_page_title-728x90-647-nonexxxnonexxxxxxezmaxscaleval100 --></div><p></p><p align="right"><cite>C has the speed and efficiency of assembly language combined with readability of assembly language </cite><br/>(Famous joke) </p><p></p><h2>This page is deprecated</h2><b>A newer version of this page is available on <a href="smetana02.html">this page</a>.</b><h2>The context</h2> PlantUML uses Graphviz/DOT to compute node positionning for every UML diagrams (except Sequence Diagram). The fact that DOT computes automatically the position of node is a key feature, and algorithms implemented in DOT usually give very good result. <p> However, there are some drawbacks of using DOT : the computation is done by an external program (dot.exe on Windows, dot on linux), and that means that : </p><ul><li>PlantUML has to create a new process for each diagram, (and communication with this new process could be source of bugs). </li><li>Users have to install DOT on their system, in addition of Java. </li><li>PlantUML is not fully portable. </li></ul> Another way of using DOT would be to use it as a library, and to link it with PlantUML using JNI (Java Native Interface) but that would not be perfect thought. <p> If a Java version of Graphviz/DOT would exist, this would allow to greatly simplify the installation and the use of PlantUML. </p><p> Unfortunatly, this does not exist today... </p><p><b>So what about porting Graphviz/DOT to Java ?</b> As Graphviz/DOT is written in C, and as Java syntax is close to C syntax it is possible to translate C source of Graphviz to Java source, although this is a large and complex task. </p><p> The good news is that we don&#39;t need to translate the whole Graphviz sources to Java : this is due to the fact that PlantUML uses only a limited portion of Graphviz. Firstly, only DOT algorithm is used (neato, ... and other are not used). Secondly, the parsing of the DOT language is not need : PlantUML could directly build the diagram in memory without generating DOT language. And thirdly all the drawing code of Graphviz is not needed anymore, since the drawing is done in Java by PlantUML. </p><p> Actually, we have already tried in 2012 and in 2014. Even those two tries were not successful, we learn a lot about the issues we have when translating C to Java. </p><p></p><h2>Hello World!</h2> It would be too long to explain here how this works (but nothing is hidden, <a href="https://github.com/plantuml/smetana">the code is public and open here</a>). To summerize, every C function of GraphViz is translated to a Java static method. <p> The translation is not finished yet, there are still some large work. However, we have translated enough to be able to run a Java version of GraphViz/Dot a some very simple diagram : two nodes and a single edge between then. The C program is: </p><pre style="text-align: left; border: 1px dashed #008DEF; line-height: 18px; padding: 15px; font-size: 13px; font-family:" courier="" new',="" courier,="" monospace;="" overflow:="" auto;'="">#include&lt;stdio.h&gt;
#include <span style="color:#2A00FF">&#34;gvc.h&#34;</span>

<span style="font-weight:bold;color:#7B0052;">void</span> pointftoString(pointf coord) <span style="font-weight:bold;color:#D3171B">{</span>
	printf(<span style="color:#2A00FF">&#34;(%f ; %f )\n&#34;</span>, coord.x, coord.y);
<span style="font-weight:bold;color:#D3171B">}</span>

<span style="font-weight:bold;color:#7B0052;">void</span> printDebugNode(Agnode_t *n) <span style="font-weight:bold;color:#D3171B">{</span>
	Agnodeinfo_t *data = (Agnodeinfo_t*) AGDATA(n);
	boxf bb = data-&gt;bb;
	printf(<span style="color:#2A00FF">&#34;*********** PRINT NODE **********\n&#34;</span>);
	printf(<span style="color:#2A00FF">&#34;width=%f\n&#34;</span>, data-&gt;width);
	printf(<span style="color:#2A00FF">&#34;height=%f\n&#34;</span>, data-&gt;height);
	printf(<span style="color:#2A00FF">&#34;ht=%f\n&#34;</span>, data-&gt;ht);
	printf(<span style="color:#2A00FF">&#34;lw=%f\n&#34;</span>, data-&gt;lw);
	printf(<span style="color:#2A00FF">&#34;rw=%f\n&#34;</span>, data-&gt;rw);
	printf(<span style="color:#2A00FF">&#34;coords=&#34;</span>);
	pointftoString(data-&gt;coord);
	printf(<span style="color:#2A00FF">&#34;bb.LL=&#34;</span>);
	pointftoString(bb.LL);
	printf(<span style="color:#2A00FF">&#34;bb.UR=&#34;</span>);
	pointftoString(bb.UR);
<span style="font-weight:bold;color:#D3171B">}</span>

<span style="font-weight:bold;color:#7B0052;">void</span> printDebugBezier(bezier *bezier) <span style="font-weight:bold;color:#D3171B">{</span>
	<span style="font-weight:bold;color:#7B0052;">int</span> i;
	printf(<span style="color:#2A00FF">&#34;bezier.size=%d\n&#34;</span>, bezier-&gt;size);
	printf(<span style="color:#2A00FF">&#34;bezier.sflag=%d\n&#34;</span>, bezier-&gt;sflag);
	printf(<span style="color:#2A00FF">&#34;bezier.eflag=%d\n&#34;</span>, bezier-&gt;eflag);
	printf(<span style="color:#2A00FF">&#34;bezier.sp&#34;</span>);
	pointftoString(bezier-&gt;sp);
	printf(<span style="color:#2A00FF">&#34;bezier.ep&#34;</span>);
	pointftoString(bezier-&gt;ep);
	<span style="font-weight:bold;color:#7B0052;">for</span> (i = 0; i &lt; bezier-&gt;size; i++) <span style="font-weight:bold;color:#D3171B">{</span>
		printf(<span style="color:#2A00FF">&#34;pt=&#34;</span>);
		pointftoString(bezier-&gt;list[i]);
	<span style="font-weight:bold;color:#D3171B">}</span>
<span style="font-weight:bold;color:#D3171B">}</span>


<span style="font-weight:bold;color:#7B0052;">void</span> printDebugEdge(Agedge_t *e) <span style="font-weight:bold;color:#D3171B">{</span>
	Agedgeinfo_t *data = (Agedgeinfo_t*) AGDATA(e);
	splines *splines = data-&gt;spl;
	boxf bb = splines-&gt;bb;
	bezier *list = splines-&gt;list;
	printf(<span style="color:#2A00FF">&#34;*********** PRINT EDGE **********\n&#34;</span>);
	printf(<span style="color:#2A00FF">&#34;splines.size=%d\n&#34;</span>, splines-&gt;size);
	printf(<span style="color:#2A00FF">&#34;bb.LL=&#34;</span>);
	pointftoString(bb.LL);
	printf(<span style="color:#2A00FF">&#34;bb.UR=&#34;</span>);
	pointftoString(bb.UR);
	printDebugBezier(&amp;list[0]);
<span style="font-weight:bold;color:#D3171B">}</span>


main(<span style="font-weight:bold;color:#7B0052;">int</span> argc, <span style="font-weight:bold;color:#7B0052;">char</span> **argv)
<span style="font-weight:bold;color:#D3171B">{</span>
Agraph_t *g;
Agnode_t *n, *m, *m2;
Agedge_t *e, *e2;
Agsym_t *a;
GVC_t *gvc;

<span style="color:#3F7F5F">/* set up a graphviz context */</span>
gvc = gvContext();

<span style="color:#3F7F5F">/* parse command line args - minimally argv[0] sets layout engine */</span>
<span style="color:#3F7F5F">// gvParseArgs(gvc, argc, argv);
</span><span style="color:#3F7F5F">/* Create a simple digraph */</span>
g = agopen(<span style="color:#2A00FF">&#34;g&#34;</span>, Agdirected, NULL);
n = agnode(g, <span style="color:#2A00FF">&#34;n&#34;</span>, 1);
m = agnode(g, <span style="color:#2A00FF">&#34;m&#34;</span>, 1);
<span style="color:#3F7F5F">//m2 = agnode(g, &#34;m2&#34;, 1);
</span>e = agedge(g, n, m, 0, 1);
<span style="color:#3F7F5F">//e2 = agedge(g, n, m2, 0, 1);
</span><span style="color:#3F7F5F">/* Set an attribute - in this case one that affects the visible rendering */</span>
<span style="color:#3F7F5F">//agsafeset(n, &#34;color&#34;, &#34;red&#34;, &#34;&#34;);
</span><span style="color:#3F7F5F">/* Compute a layout using layout engine from command line args */</span>
<span style="font-weight:bold;color:#7B0052;">int</span> ret = gvLayoutJobs(gvc, g);

printDebugNode(n);
printDebugNode(m);
printDebugEdge(e);

<span style="font-weight:bold;color:#D3171B">}</span></pre> The corresponding Java program: <pre style="text-align: left; border: 1px dashed #008DEF; line-height: 18px; padding: 15px; font-size: 13px; font-family:" courier="" new',="" courier,="" monospace;="" overflow:="" auto;'=""><span style="font-weight:bold;color:#7B0052;">public</span> <span style="font-weight:bold;color:#7B0052;">class</span> Demo01 <span style="font-weight:bold;color:#D3171B">{</span>

  <span style="font-weight:bold;color:#7B0052;">public</span> <span style="font-weight:bold;color:#7B0052;">static</span> <span style="font-weight:bold;color:#7B0052;">void</span> main(String[] args) <span style="font-weight:bold;color:#7B0052;">throws</span> IOException <span style="font-weight:bold;color:#D3171B">{</span>

    Agraph_s g = agopen(<span style="font-weight:bold;color:#7B0052;">new</span> CString(<span style="color:#2A00FF">&#34;g&#34;</span>), Agdirected, <span style="font-weight:bold;color:#7B0052;">null</span>);
    Agnode_s n = agnode(g, <span style="font-weight:bold;color:#7B0052;">new</span> CString(<span style="color:#2A00FF">&#34;n&#34;</span>), <span style="font-weight:bold;color:#7B0052;">true</span>);
    Agnode_s m = agnode(g, <span style="font-weight:bold;color:#7B0052;">new</span> CString(<span style="color:#2A00FF">&#34;m&#34;</span>), <span style="font-weight:bold;color:#7B0052;">true</span>);
    <span style="color:#3F7F5F">// Agnode_s m2 = agnode(g, new CString(&#34;m2&#34;), true);
</span>    Agedge_s e = agedge(g, n, m, null, <span style="font-weight:bold;color:#7B0052;">true</span>);
    <span style="color:#3F7F5F">// Agedge_s e2 = agedge(g, n, m2, null, true);
</span>    System.err.println(<span style="color:#2A00FF">&#34;n=&#34;</span> + n);
    System.err.println(<span style="color:#2A00FF">&#34;m=&#34;</span> + m);
    <span style="color:#3F7F5F">// System.err.println(&#34;m=&#34; + m2);
</span>    System.err.println(<span style="color:#2A00FF">&#34;e=&#34;</span> + e);

    GVC_s gvc = gvContext();

    <span style="color:#3F7F5F">/* Compute a layout using layout engine from command line args */</span>
    gvLayoutJobs(gvc, g);

    printDebugNode(n);
    printDebugNode(m);
    printDebugEdge(e);
  <span style="font-weight:bold;color:#D3171B">}</span>


  <span style="font-weight:bold;color:#7B0052;">private</span> <span style="font-weight:bold;color:#7B0052;">static</span> <span style="font-weight:bold;color:#7B0052;">void</span> printDebugEdge(Agedge_s e) <span style="font-weight:bold;color:#D3171B">{</span>
    System.err.println(<span style="color:#2A00FF">&#34;*********** PRINT EDGE ********** &#34;</span> + getUID(e));
    <span style="font-weight:bold;color:#7B0052;">final</span> Agedgeinfo_t data = (Agedgeinfo_t) Macro.AGDATA(e)
	  .castTo(Agedgeinfo_t.class);
    <span style="font-weight:bold;color:#7B0052;">final</span> splines splines = (splines) data.getPtr(<span style="color:#2A00FF">&#34;spl&#34;</span>);
    __struct__&lt;boxf&gt; bb = splines.getStruct(<span style="color:#2A00FF">&#34;bb&#34;</span>);
    <span style="font-weight:bold;color:#7B0052;">final</span> bezier list = (bezier) splines.getPtr(<span style="color:#2A00FF">&#34;list&#34;</span>);
    System.err.println(<span style="color:#2A00FF">&#34;splines.UID=&#34;</span> + ((StarStruct) splines).getUID36());
    System.err.println(<span style="color:#2A00FF">&#34;splines.size=&#34;</span> + splines.getInt(<span style="color:#2A00FF">&#34;size&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;bb.LL=&#34;</span> + pointftoString(bb.getStruct(<span style="color:#2A00FF">&#34;LL&#34;</span>)));
    System.err.println(<span style="color:#2A00FF">&#34;bb.UR=&#34;</span> + pointftoString(bb.getStruct(<span style="color:#2A00FF">&#34;UR&#34;</span>)));
    printDebugBezier((bezier) splines.getPtr(<span style="color:#2A00FF">&#34;list&#34;</span>).getPtr());

  <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#7B0052;">public</span> <span style="font-weight:bold;color:#7B0052;">static</span> String getUID(Object o) <span style="font-weight:bold;color:#D3171B">{</span>
    <span style="font-weight:bold;color:#7B0052;">if</span> (o <span style="font-weight:bold;color:#7B0052;">instanceof</span> StarArray) <span style="font-weight:bold;color:#D3171B">{</span>
      <span style="font-weight:bold;color:#7B0052;">return</span> ((StarArray) o).getUID36();
    <span style="font-weight:bold;color:#D3171B">}</span>
    <span style="font-weight:bold;color:#7B0052;">return</span> ((StarStruct) o).getUID36();
  <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#7B0052;">private</span> <span style="font-weight:bold;color:#7B0052;">static</span> <span style="font-weight:bold;color:#7B0052;">void</span> printDebugBezier(bezier bezier) <span style="font-weight:bold;color:#D3171B">{</span>
    System.err.println(<span style="color:#2A00FF">&#34;bezier.size=&#34;</span> + bezier.getInt(<span style="color:#2A00FF">&#34;size&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;bezier.sflag=&#34;</span> + bezier.getInt(<span style="color:#2A00FF">&#34;sflag&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;splines.eflag=&#34;</span> + bezier.getInt(<span style="color:#2A00FF">&#34;eflag&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;bezier.sp=&#34;</span> + pointftoString(bezier.getStruct(<span style="color:#2A00FF">&#34;sp&#34;</span>)));
    System.err.println(<span style="color:#2A00FF">&#34;bezier.ep=&#34;</span> + pointftoString(bezier.getStruct(<span style="color:#2A00FF">&#34;ep&#34;</span>)));
    System.err.println(<span style="color:#2A00FF">&#34;bezier.list=&#34;</span> + getUID(bezier.getPtr(<span style="color:#2A00FF">&#34;list&#34;</span>)));
    <span style="font-weight:bold;color:#7B0052;">for</span> (<span style="font-weight:bold;color:#7B0052;">int</span> i = 0; i &lt; bezier.getInt(<span style="color:#2A00FF">&#34;size&#34;</span>); i++) <span style="font-weight:bold;color:#D3171B">{</span>
      <span style="font-weight:bold;color:#7B0052;">final</span> __ptr__ pt = bezier.getPtr(<span style="color:#2A00FF">&#34;list&#34;</span>).plus(i).getPtr();
      System.err.println(<span style="color:#2A00FF">&#34;pt=&#34;</span> + pointftoString(pt));
    <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#7B0052;">private</span> <span style="font-weight:bold;color:#7B0052;">static</span> <span style="font-weight:bold;color:#7B0052;">void</span> printDebugNode(Agnode_s n) <span style="font-weight:bold;color:#D3171B">{</span>
    System.err.println(<span style="color:#2A00FF">&#34;*********** PRINT NODE ********** &#34;</span>);
    <span style="font-weight:bold;color:#7B0052;">final</span> Agnodeinfo_t data = (Agnodeinfo_t) Macro.AGDATA(n)
	  .castTo(Agnodeinfo_t.class);
    System.err.println(<span style="color:#2A00FF">&#34;width=&#34;</span> + data.getDouble(<span style="color:#2A00FF">&#34;width&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;height=&#34;</span> + data.getDouble(<span style="color:#2A00FF">&#34;height&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;ht=&#34;</span> + data.getDouble(<span style="color:#2A00FF">&#34;ht&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;lw=&#34;</span> + data.getDouble(<span style="color:#2A00FF">&#34;lw&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;rw=&#34;</span> + data.getDouble(<span style="color:#2A00FF">&#34;rw&#34;</span>));
    System.err.println(<span style="color:#2A00FF">&#34;coord=&#34;</span> + pointftoString(data.getStruct(<span style="color:#2A00FF">&#34;coord&#34;</span>)));

    __struct__&lt;boxf&gt; bb = data.getStruct(<span style="color:#2A00FF">&#34;bb&#34;</span>);
    System.err.println(<span style="color:#2A00FF">&#34;bb.LL=&#34;</span> + pointftoString(bb.getStruct(<span style="color:#2A00FF">&#34;LL&#34;</span>)));
    System.err.println(<span style="color:#2A00FF">&#34;bb.UR=&#34;</span> + pointftoString(bb.getStruct(<span style="color:#2A00FF">&#34;UR&#34;</span>)));
    <span style="color:#3F7F5F">// TODO Auto-generated method stub
</span>  <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#7B0052;">private</span> <span style="font-weight:bold;color:#7B0052;">static</span> String pointftoString(__struct__&lt;pointf&gt; point) <span style="font-weight:bold;color:#D3171B">{</span>
    <span style="font-weight:bold;color:#7B0052;">final</span> StringBuilder sb = <span style="font-weight:bold;color:#7B0052;">new</span> StringBuilder();
    sb.append(<span style="color:#2A00FF">&#34;(&#34;</span>);
    sb.append(point.getDouble(<span style="color:#2A00FF">&#34;x&#34;</span>));
    sb.append(<span style="color:#2A00FF">&#34; ; &#34;</span>);
    sb.append(point.getDouble(<span style="color:#2A00FF">&#34;y&#34;</span>));
    sb.append(<span style="color:#2A00FF">&#34;)&#34;</span>);
    <span style="font-weight:bold;color:#7B0052;">return</span> sb.toString();

  <span style="font-weight:bold;color:#D3171B">}</span>

  <span style="font-weight:bold;color:#7B0052;">private</span> <span style="font-weight:bold;color:#7B0052;">static</span> String pointftoString(__ptr__ point) <span style="font-weight:bold;color:#D3171B">{</span>
    <span style="font-weight:bold;color:#7B0052;">final</span> StringBuilder sb = <span style="font-weight:bold;color:#7B0052;">new</span> StringBuilder();
    sb.append(<span style="color:#2A00FF">&#34;(&#34;</span>);
    sb.append(point.getDouble(<span style="color:#2A00FF">&#34;x&#34;</span>));
    sb.append(<span style="color:#2A00FF">&#34; ; &#34;</span>);
    sb.append(point.getDouble(<span style="color:#2A00FF">&#34;y&#34;</span>));
    sb.append(<span style="color:#2A00FF">&#34;)&#34;</span>);
    <span style="font-weight:bold;color:#7B0052;">return</span> sb.toString();
  <span style="font-weight:bold;color:#D3171B">}</span>
<span style="font-weight:bold;color:#D3171B">}</span></pre> Running <code>Demo01.java</code> class prints the following result: <div class="scriptplantu"><pre>*********** PRINT NODE ********** 
SKIPPING gv_fixLocale
width=0.75
height=0.5
ht=36.0
lw=27.0
rw=27.0
coord=(27.0 ; 90.0)
bb.LL=(0.0 ; 0.0)
bb.UR=(0.0 ; 0.0)
*********** PRINT NODE ********** 
width=0.75
height=0.5
ht=36.0
lw=27.0
rw=27.0
coord=(27.0 ; 18.0)
bb.LL=(0.0 ; 0.0)
bb.UR=(0.0 ; 0.0)
*********** PRINT EDGE ********** am
splines.UID=ehr
splines.size=1
bb.LL=(0.0 ; 0.0)
bb.UR=(0.0 ; 0.0)
bezier.size=4
bezier.sflag=0
splines.eflag=1
bezier.sp=(0.0 ; 0.0)
bezier.ep=(27.0 ; 36.10433368267388)
bezier.list=ei4
pt=(27.0 ; 71.69662499427795)
pt=(27.0 ; 63.982712746350444)
pt=(27.0 ; 54.712457302958484)
pt=(27.0 ; 46.11242283518388)

</pre></div> And this is the same result as the C program! <h2>What&#39;s next ?</h2> A lot of work! <p> Clusters, edges decoration... and many other things are not working because the corresponding code is not translated yet. </p><p><u>However, we have proven that it is feasible to translate GraphViz/DOT in Java.</u></p><p> The next step is to run a slightly more complex diagram, with 3 nodes and 2 edges. </p><p> Then we will have to write some glue code to call this very basic version of DOT in Java. This will allow the generation of very simple Class Diagrams without GraphViz/DOT installed. </p><p></p><span id="ezoic-pub-ad-placeholder-104"></span><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-234x60-104-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-468x60-104-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-728x90-104-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-970x250-104-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-300x250x3-104-nonexxxnonexxxxxxezmaxscaleval100 --><!-- ezoic_pub_ad_placeholder-104-bottom_of_page-970x90-104-nonexxxnonexxxxxxezmaxscaleval100 --></div><style>.btm{text-align:center}.btm a{text-decoration:none;color:#637282}.btm a:hover{color:#0366d6}</style><div class="btm"><hr/><a href="https://g.ezoic.net/privacy/plantuml.com"><small>Privacy Policy</small></a>      <a href="direct-sales.html"><small>Advertise</small></a><p></p></div><script>var sc_project=11133780;var sc_invisible=1;var sc_security="3da8bfdb";</script><script async="" src="https://www.statcounter.com/counter/counter.js"></script><!--[selectrongo:done]--><script type="text/javascript">
				var __inScopeForCCPA = false;
		function __uspapi(command, version, callback) {
			var response = null;
			var successs = false;
			if (command === "getUSPData" && version === 1) {
				var uspString = "1"; // Version
				if (__inScopeForCCPA) {
					uspString += "N"; // Has Explicit Notice for Opt Out been provided (ex footer or minor consent modal)
					var result;
					var consentCookie = (result = new RegExp('(?:^|; )ezoccpaconsent=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
					if (consentCookie === "nonconsent") {
						uspString += "Y";
					}
					else {
						uspString += "N";
					}
					uspString += "N" // Is pub a signatory to the IAB Limited Service Provider Agreement (http://www.iabprivacy.com/)
				}
				else {
					uspString += "---";
				}
				response = {
					uspString: uspString,
					version: 1
				};
				success = true;
			}
			return callback(response, success);
		};
		function __receiveUspapiMessage(event) {
			if (event.data.hasOwnProperty('__uspapiCall')) {
				__uspapi('getUSPData', 1, function(uspData, success) {
					event.source.postMessage({
						__uspapiReturn: {
							returnValue: uspData,
							success: success,
							callId: event.data.__uspapiCall.callId
						}
					},
					event.origin);
				});
			}
			return null;
		};
		window.addEventListener("message", __receiveUspapiMessage, false);
</script>
<script>__ez.queue.addFile('/tardisrocinante/vitals.js', '/tardisrocinante/vitals.js?gcb=2&cb=3', false, ['/parsonsmaize/mulvane.js'], true, false, true, false);</script>
<script>var _audins_dom="plantuml_com",_audins_did=173770;__ez.queue.addDelayFunc("audins.js","__ez.script.add", "//go.ezodn.com/detroitchicago/audins.js?cb=195-2");</script><noscript><div style="display:none;"><img src="https://pixel.quantserve.com/pixel/p-31iz6hfFutd16.gif?labels=Domain.plantuml_com,DomainId.173770" border="0" height="1" width="1" alt="Quantcast"/></div></noscript>
<script>__ez.queue.addFile('/beardeddragon/drake.js', '/beardeddragon/drake.js?gcb=2&cb=4', false, [], true, false, true, false);</script>
<script type="text/javascript" style='display:none;'>var __ez_dims = (function() {
		var setCookie = function( name, content, expiry ) {
			return document.cookie = name+'='+content+((expiry)?';expires='+(new Date(Math.floor(new Date().getTime()+expiry*1000)).toUTCString()):'')+';path=/';
		};
		var ffid = 1;
		var oh = window.screen.height;
		var ow = window.screen.width;
		var h = ffid === 1 ? oh : (oh > ow) ? oh : ow;
		var w = ffid === 1 ? ow : (oh > ow) ? ow : oh;
		var uh = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;
		var uw = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
		setCookie('ezds', encodeURIComponent('ffid='+ffid+',w='+w+',h='+h), (31536e3*7));
		setCookie('ezohw', encodeURIComponent('w='+uw+',h='+uh), (31536e3*7));
	})();</script>
<script type='text/javascript' style='display:none;' async>__ez.queue.addFile('/parsonsmaize/chanute.js', '/parsonsmaize/chanute.js?a=a&cb=7&dcb=195-2&shcb=34', true, ['/parsonsmaize/mulvane.js'], true, false, false, false);</script>
<script type='text/javascript' style='display:none;' async>__ez.queue.addFile('/porpoiseant/jellyfish.js', '/porpoiseant/jellyfish.js?a=a&cb=10&dcb=195-2&shcb=34', false, [], true, false, false, false);</script></body></html>